/* Copyright (c) 2009, Enric Rodriguez (enrodri86@gmail.com)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 	- Redistributions of source code must retain the above copyright
 * 	notice,	this list of conditions and the following disclaimer.
 * 	- Redistributions in binary form must reproduce the above copyright
 * 	notice, this list of conditions and the following disclaimer in the
 * 	documentation and/or other materials provided with the distribution.
 * 	- Neither the name of the <ORGANIZATION> nor the names of its
 * 	contributors may be used to endorse or promote products derived from
 * 	this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package es.enrodri86.mmo.auth.server;

import java.io.IOException;
import java.util.Map;

import es.enrodri86.mmo.auth.client.AuthConnection;
import es.enrodri86.mmo.auth.shared.AuthException;
import es.enrodri86.mmo.auth.shared.Captcha;
import es.enrodri86.mmo.auth.shared.Game;
import es.enrodri86.mmo.auth.shared.GameServer;
import es.enrodri86.mmo.auth.shared.LoginException;

/**
 * This interface is what the developer should implement in order to provide
 * its own server implementation. It contains the methods for answering
 * client requests. A {@link String} is used as a session key for most methods.
 *
 * This class will be used by a servlet in a HTTP/HTTPS authentication context.
 *
 * This interface extends {@link Runnable} in order to allow {@link AuthServer}
 * to perform its tasks if needed.
 * @author enrodri86
 * @see AuthConnection
 */
public interface AuthServer extends Runnable{

	/**
	 * When a client connects, the server can answer with an exception, telling
	 * it is too busy, down for maintenance, or that this IP address is banned,
	 * whatever...
	 * @throws IOException
	 * @throws AuthException
	 */
	public void connect(String sessionKey,String ip) throws AuthException;

	/**
	 * The authenticaton server may have different policies for enabling or
	 * disabling captcha requirements depending on the IP address. For example,
	 * in order to allow automatic log on for administrators connecting from
	 * a local area network.
	 * @return
	 */
	public boolean isCaptchaRequired(String sessionKey);

	/**
	 * The server may have different captcha policies depending on the client's
	 * IP address, or time. The developer may decide to change the generator in
	 * order to make a safer system.
	 * @return
	 */
	public Captcha getCaptcha(String sessionKey);

	/**
	 *
	 * @param user
	 * @param pass
	 * @param captcha
	 * @return
	 * @throws LoginException
	 */
	public boolean login(String sessionKey, String user, String pass, String captcha) throws LoginException;

	/**
	 * Used when you let your client choose among a variety of games to play.
	 * Take care of the server's IDs that you send with this list of games,
	 * you may not want users to play at development servers.
	 * @return
	 */
	public Map<String,Game> getGameList(String sessionKey);

	/**
	 * Used when the client chooses a game to play.
	 * @param g
	 * @throws IOException
	 * @throws AuthException
	 */
	public void chooseGame(String sessionKey,String gameID) throws IOException, AuthException;

	/**
	 * I a HTTP/HTTPS environment (used by {@link AuthServlet}) this method
	 * not return until we are sure the gameServer retrieved the sessionKey.
	 * As soon as this method returns the client is supposed be able to connect
	 * to the {@link GameServer}. On a TCP environment this is done by the
	 * {@link #getSession()} method.
	 * @param sessionKey
	 * @param gameServerID
	 * @throws IOException
	 * @throws AuthException
	 */
	public void chooseGameServer(String sessionKey, String gameServerID) throws IOException, AuthException;

	/**
	 * The full list of game servers available.
	 * The API will only send those specified in {@link #getGameList(String)},
	 * note that {@link Game} carries a list of {@link GameServer} IDs.
	 * @see #getGameList(String)
	 * @return
	 */
	public Map<String,GameServer> getGameServerList();

	/**
	 * In a HTTP/HTTPS servlet context, the servlet will ask for a session to
	 * send to the client once it connects. Sessions may be relased once they
	 * are used, because of inactivity, or only when the player stops playing
	 * or logs off the game server. With other protocols, the session may be
	 * asked at the end of the process, for example if you are using a plain
	 * TCP socket, you only need to send the session once.
	 * @return
	 */
	public String getSession();

}
